﻿//using CSRedis;
//using System;
//using System.Collections.Generic;
//using System.Linq;

//namespace Common.Framework.Core.Cache
//{
//    /// <summary>
//    /// Redis 缓存
//    /// </summary>
//    public class RedisCacheMiddleware : ICache
//    {
//        /// <summary>
//        /// 所有缓存key缓存的key
//        /// </summary>
//        private readonly string RedisAllKey = ":SystemCacheKeys";

//        /// <summary>
//        /// 过期时间 3天
//        /// </summary>
//        private readonly int RedisAllKeyExpiresAtSecond = 259200;

//        /// <summary>
//        /// 锁
//        /// </summary>
//        private readonly static object locker = new object();

//        /// <summary>
//        /// 构造函数
//        /// </summary>
//        /// <param name="redis">redis</param>
//        public RedisCacheMiddleware()
//        {

//        }

//        /// <summary>
//        /// 获取缓存值
//        /// </summary>
//        /// <param name="key"></param>
//        /// <returns></returns>
//        public TEntity Get<TEntity>(string key)
//        {
//            var cacheValue = GetRedisValue(key);
//            if (string.IsNullOrWhiteSpace(cacheValue))
//            {
//                return default(TEntity);
//            }
//            return JsonHelper.DeserializeObject<TEntity>(cacheValue);
//        }

//        /// <summary>
//        /// 添加缓存内容(滑动过期)
//        /// </summary>
//        /// <param name="key"></param>
//        /// <param name="value"></param>
//        public void SetSliding<TEntity>(string key, TEntity value, int expiresAtSecond)
//        {
//            SetRedisValue(key, value, expiresAtSecond);
//        }

//        /// <summary>
//        /// 添加缓存内容(定时过期)
//        /// </summary>
//        /// <param name="key"></param>
//        /// <param name="value"></param>
//        public void Set<TEntity>(string key, TEntity value, int expiresAtSecond)
//        {
//            SetRedisValue(key, value, expiresAtSecond);
//        }

//        /// <summary>
//        /// 添加缓存内容(定时过期)
//        /// </summary>
//        /// <param name="key"></param>
//        /// <param name="value"></param>
//        public void Set<TEntity>(string key, TEntity value, DateTime expires)
//        {
//            var ts = expires - DateTime.Now;
//            SetRedisValue(key, value, (int)ts.TotalSeconds);
//        }

//        /// <summary>
//        /// 添加或获取缓存
//        /// </summary>
//        /// <typeparam name="TEntity">泛型实体</typeparam>
//        /// <param name="fuc">数据源方法</param>
//        /// <param name="key">缓存key</param>
//        /// <param name="cacheSeconds">缓存时间（秒）</param>
//        /// <returns></returns>
//        public TEntity Set<TEntity>(Func<TEntity> fuc, string key, int cacheSeconds)
//        {
//            var cacheValue = Get<TEntity>(key);
//            if (cacheValue != null)
//            {
//                return cacheValue;
//            }
//            else
//            {
//                var fucValue = fuc();
//                Set(key, fucValue, cacheSeconds);
//                return fucValue;
//            }
//        }

//        /// <summary>
//        /// 添加或获取缓存
//        /// </summary>
//        /// <typeparam name="TEntity">泛型实体</typeparam>
//        /// <param name="fuc">数据源方法</param>
//        /// <param name="key">缓存key</param>
//        /// <param name="hashId"></param>
//        /// <param name="expiresAtSecond">缓存时间（秒）</param>
//        /// <param name="isCache">是否读取换存</param>
//        /// <returns></returns>
//        public TEntity GetHash<TEntity>(Func<TEntity> fuc, string key, string hashId, int expiresAtSecond, bool isCache = true)
//        {
//            var cacheValue = GetHash<TEntity>(key, hashId);
//            if (cacheValue != null && isCache)
//            {
//                return cacheValue;
//            }
//            else
//            {
//                if (fuc != null)
//                {
//                    var fucValue = fuc();
//                    SetHash<TEntity>(key, hashId, fucValue, expiresAtSecond);
//                    return fucValue;
//                }
//            }
//            return default;
//        }

//        /// <summary>
//        /// 获取Hash表某条字段的值
//        /// </summary>
//        /// <typeparam name="TEntity">泛型</typeparam>
//        /// <param name="key">缓存Key</param>
//        /// <param name="hashId">hash表字段Id</param>
//        /// <returns></returns>
//        public TEntity GetHash<TEntity>(string key, string hashId)
//        {
//            var realKey = GetKey(key);
//            return RedisHelper.HGet<TEntity>(realKey, hashId);
//        }

//        /// <summary>
//        /// 获取Hash表所有记录
//        /// </summary>
//        /// <typeparam name="TEntity">泛型</typeparam>
//        /// <param name="key">缓存Key</param>
//        /// <returns></returns>
//        public List<TEntity> GetHash<TEntity>(string key)
//        {
//            var realKey = GetKey(key);
//            var value = RedisHelper.HGetAll<TEntity>(realKey);
//            if (!value.Any())
//            {
//                return new List<TEntity>();
//            }
//            var list = new List<TEntity>();
//            try
//            {
//                foreach (var item in value)
//                {
//                    list.Add(item.Value);
//                }
//            }
//            catch (Exception ex)
//            {
//                LogHelper.WriteLog("GetHash", ex);
//            }
//            return list;
//        }

//        /// <summary>
//        /// 清除缓存
//        /// </summary>
//        /// <param name="key">待清除的key</param>
//        public void Remove(string key)
//        {
//            var realKey = GetKey(key);
//            RedisHelper.Del(realKey);
//            RedisHelper.SRem(RedisAllKey, key);
//        }

//        /// <summary>
//        /// 清除所有缓存
//        /// </summary>
//        public void Remove()
//        {
//            var list = SMembers(RedisAllKey, true);
//            lock (locker)
//            {
//                foreach (var key in list)
//                {
//                    if (!key.Contains("CurrentApp") && !key.Contains("Lockers"))
//                    {
//                        Remove(key);
//                    }
//                }
//            }
//        }


//        /// <summary>
//        /// 添加Hash表
//        /// </summary>
//        /// <param name="key">缓存Key</param>
//        /// <param name="keyValuePairs">待设置的值</param>
//        /// <param name="expiresAtSecond">过期时间</param>
//        /// <returns></returns>
//        public void SetHash<TEntity>(string key, IEnumerable<KeyValuePair<string, TEntity>> keyValuePairs, int expiresAtSecond)
//        {
//            var realKey = GetKey(key);
//            PushKeys(key);
//            foreach (var item in keyValuePairs)
//            {
//                RedisHelper.HSet(realKey, item.Key, item.Value);
//            }
//            Expire(realKey, expiresAtSecond);
//        }

//        /// <summary>
//        /// 添加Hash表
//        /// </summary>
//        /// <param name="key">缓存Key</param>
//        /// <param name="hashId"></param>
//        /// <param name="value"></param>
//        /// <param name="expiresAtSecond">过期时间</param>
//        /// <returns></returns>
//        public void SetHash<TEntity>(string key, string hashId, TEntity value, int expiresAtSecond)
//        {
//            if (value != null)
//            {
//                var realKey = GetKey(key);
//                PushKeys(key);
//                RedisHelper.HSet(realKey, hashId, value);
//                Expire(realKey, expiresAtSecond);
//            }
//        }


//        /// <summary>
//        /// 清楚key以startsWithKey开头的缓存
//        /// </summary>
//        /// <param name="startsWithKey"></param>
//        public void RemoveStartsWith(string startsWithKey)
//        {
//            string[] keys = SMembers(RedisAllKey, true);
//            if (keys != null && keys.Length > 0)
//            {
//                for (int i = 0; i < keys.Length; i++)
//                {
//                    if (keys[i].StartsWith(startsWithKey))
//                    {
//                        Remove(keys[i]);
//                    }
//                }
//            }
//        }


//        #region 列表(list)  列表可以有序的存储多个字符串（字符串可以重复）等操作；列表是通过链表来实现的，所以它添加新元素的速度非常快。

//        #region 同步
//        /// <summary>
//        /// 向列表中增加一个或多个值
//        /// 示例：RPush("my-list", "item1", "item2", "item3", "item4"); 
//        /// </summary>
//        /// <typeparam name="TEntity">值类型</typeparam>
//        /// <param name="key">缓存key（不含前缀）</param>
//        /// <param name="value">值</param>
//        /// <returns></returns>
//        public long RPush<TEntity>(string key, params TEntity[] value)
//        {
//            var realKey = GetKey(key);
//            var result = RedisHelper.RPush(realKey, value);
//            Expire(realKey, 60 * 24 * 60);
//            return result;
//        }

//        /// <summary>
//        /// 获取列表指定范围内元素
//        /// </summary>
//        /// <param name="key">缓存key（不含前缀）</param>
//        /// <param name="start">起始索引</param>
//        /// <param name="stop">结束索引（-1即可返回所有元素）</param>
//        /// <returns></returns>
//        public string[] LRange(string key, long start = 0, long stop = -1)
//        {
//            var realKey = GetKey(key);
//            return RedisHelper.LRange(realKey, start, stop);
//        }
//        #endregion

//        #region 异步
//        /// <summary>
//        /// 向列表中增加一个或多个值
//        /// 示例：RPush("my-list", "item1", "item2", "item3", "item4"); 
//        /// 
//        /// </summary>
//        /// <typeparam name="TEntity">值类型</typeparam>
//        /// <param name="key">缓存key（不含前缀）</param>
//        /// <param name="value">值</param>
//        /// <returns></returns>
//        public async System.Threading.Tasks.Task<long> RPushAsync<TEntity>(string key, params TEntity[] value)
//        {
//            var realKey = GetKey(key);
//            var result = await RedisHelper.RPushAsync(realKey, value);
//            await ExpireAsync(realKey, 60 * 24 * 60);
//            return result;
//        }

//        /// <summary>
//        /// 获取列表指定范围内元素
//        /// </summary>
//        /// <param name="key">缓存key（不含前缀）</param>
//        /// <param name="start">起始索引</param>
//        /// <param name="stop">结束索引（-1即可返回所有元素）</param>
//        /// <returns></returns>
//        public async System.Threading.Tasks.Task<string[]> LRangeAsync(string key, long start, long stop = -1)
//        {
//            var realKey = GetKey(key);
//            return await RedisHelper.LRangeAsync(realKey, start, stop);
//        }
//        #endregion

//        #endregion

//        #region  有序集合(sorted set)

//        #region 同步
//        /// <summary>
//        /// 向集合添加一个或多个成员
//        /// </summary>
//        /// <typeparam name="TEntity">泛型</typeparam>
//        /// <param name="key">缓存key</param>
//        /// <param name="seconds">过期秒数</param>
//        /// <param name="members"一个或多个成员></param>
//        /// <returns></returns>
//        public long SAdd<TEntity>(string key, int seconds, params TEntity[] members)
//        {
//            var realKey = GetKey(key);
//            Expire(realKey, seconds);
//            return RedisHelper.SAdd(realKey, members);
//        }

//        /// <summary>
//        /// 返回集合中的所有成员
//        /// </summary>
//        /// <param name="key">缓存key</param>
//        /// <param name="addprefix">key是否已经加了前缀</param>
//        /// <returns></returns>
//        public string[] SMembers(string key, bool addprefix = false)
//        {
//            if (!addprefix)
//            {
//                key = GetKey(key);
//            }
//            return RedisHelper.SMembers(key);
//        }
//        #endregion

//        #region 异步
//        /// <summary>
//        /// 向集合添加一个或多个成员
//        /// </summary>
//        /// <typeparam name="TEntity">泛型</typeparam>
//        /// <param name="key">缓存key</param>
//        /// <param name="seconds">过期秒数</param>
//        /// <param name="members"一个或多个成员></param>
//        /// <returns></returns>
//        public async System.Threading.Tasks.Task<long> SAddAsync<TEntity>(string key, int seconds, params TEntity[] members)
//        {
//            var realKey = GetKey(key); await ExpireAsync(realKey, seconds);
//            return await RedisHelper.SAddAsync(realKey, members);
//        }

//        /// <summary>
//        /// 返回集合中的所有成员
//        /// </summary>
//        /// <param name="key">缓存key</param>
//        /// <param name="addprefix">key是否已经加了前缀</param>
//        /// <returns></returns>
//        public async System.Threading.Tasks.Task<string[]> SMembersAsync(string key, bool addprefix = false)
//        {
//            if (!addprefix)
//            {
//                key = GetKey(key);
//            }
//            return await RedisHelper.SMembersAsync(key);
//        }
//        #endregion
//        #endregion

//        #region Distributed Locks
//        /// <summary>
//        /// 开启分布式锁，若超时返回null
//        /// </summary>
//        /// <param name="key">锁名称</param>
//        /// <param name="timeoutSeconds">超时（秒）</param>
//        /// <param name="autoDelay">自动延长锁超时时间，看门狗线程的超时时间为timeoutSeconds/2 ， 在看门狗线程超时时间时自动延长锁的时间为timeoutSeconds。除非程序意外退出，否则永不超时。</param>
//        /// <returns>false 锁定中 true 未锁定</returns>
//        public CSRedisClientLock LockTake(string key, int timeoutSeconds, bool autoDelay = false)
//        {
//            return RedisHelper.Lock(key, timeoutSeconds, autoDelay);
//        }

//        /// <summary>
//        /// 释放锁
//        /// </summary>
//        /// <param name="cSRedisClientLock"></param>
//        /// <returns></returns>
//        public bool LockRelease(CSRedisClientLock cSRedisClientLock)
//        {
//            if (cSRedisClientLock != null)
//            {
//                return cSRedisClientLock.Unlock();
//            }
//            return true;
//        }
//        #endregion

//        #region 私有方法

//        /// <summary>
//        /// 获取Key
//        /// </summary>
//        /// <param name="key">关键字</param>
//        /// <returns></returns>
//        private string GetKey(string key)
//        {
//            if (!key.StartsWith(":"))
//            {
//                key = $":{key}";
//            }
//            return key;
//        }

//        /// <summary>
//        /// 将所有的Key缓存起来
//        /// </summary>
//        /// <param name="key">要缓存的Key</param>
//        private void PushKeys(string key)
//        {
//            if (key.Contains("Lockers"))//黑词不加入清除所有的set中，防止管理端乱点清除所有
//            {
//                return;
//            }
//            RedisHelper.SAdd(RedisAllKey, key);//添加到set中，已记录所有的缓存key,方便清除所有
//            Expire(RedisAllKey, RedisAllKeyExpiresAtSecond);

//        }

//        /// <summary>
//        /// 添加缓存内容(定时过期)
//        /// </summary>
//        /// <param name="key"></param>
//        /// <param name="value"></param>
//        private void SetRedisValue<TEntity>(string key, TEntity value, int expiresAtSecond)
//        {
//            var realKey = GetKey(key);
//            if (value == null)
//            {
//                return;
//            }
//            lock (locker)
//            {
//                RedisHelper.Set(realKey, JsonHelper.SerializeObject(value), expiresAtSecond);
//            }
//            PushKeys(key);
//        }

//        /// <summary>
//        /// 获取缓存内容
//        /// </summary>
//        /// <param name="key">key</param>
//        /// <returns></returns>
//        private string GetRedisValue(string key)
//        {
//            var realKey = GetKey(key);
//            Expire(RedisAllKey, RedisAllKeyExpiresAtSecond);
//            return RedisHelper.Get(realKey);
//        }

//        /// <summary>
//        /// 为给定 key 设置过期时间
//        /// </summary>
//        /// <param name="key">不含prefix前辍</param>
//        /// <param name="seconds">过期秒数</param>
//        private void Expire(string key, int seconds)
//        {
//            RedisHelper.Expire(key, seconds);
//        }

//        /// <summary>
//        /// 为给定 key 设置过期时间
//        /// </summary>
//        /// <param name="key">缓存key</param>
//        /// <param name="seconds">过期秒数</param>
//        /// <returns></returns>
//        private async System.Threading.Tasks.Task<bool> ExpireAsync(string key, int seconds)
//        {
//            return await RedisHelper.ExpireAsync(key, seconds);
//        }
//        #endregion
//    }
//}
